﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace CRL.LambdaQuery
{
    public partial class ExpressionVisitor
    {

        public object MethodCallInvokeBase(Expression callExp, out object target)
        {
            target = null;
            if (callExp is LambdaExpression)
            {
                return (callExp as LambdaExpression).Compile().DynamicInvoke();
            }
            else if (callExp is MethodCallExpression)
            {
                return VisitMethodCall(callExp as MethodCallExpression,out target);
            }
            return Expression.Lambda(callExp).Compile().DynamicInvoke();
        }

        private object VisitMethodCall(MethodCallExpression callExp, out object target)
        {
            target = null;
            var arguments = new List<object>();
            foreach (var item in callExp.Arguments)
            {
                if (item.Type.FullName.StartsWith("System.Linq.Expressions.Expression"))
                {
                    var unaryExpression = item as UnaryExpression;
                    arguments.Add(unaryExpression.Operand);
                }
                else
                {
                    arguments.Add(MethodCallInvokeBase(item, out var _t));
                }
            }
            object result;
            if (callExp.Object == null)
            {
                result = callExp.Method.Invoke(this, arguments.ToArray());
            }
            else
            {
                var obj = MethodCallInvokeBase(callExp.Object, out var _t);
                target = obj;
                result = callExp.Method.Invoke(obj, arguments.ToArray());
            }
            return result;
        }
    }
}
